package com.java.practise.tags;

import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.List;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;

@SuppressWarnings("serial")
public class PojoPaginated extends Paginated {
	@Override
	public int doEndTag() throws JspException {
		try {
			JspWriter out = pageContext.getOut();
			out.print(paginatedTable());
		}
		catch(Exception ex) {
			throw new JspException("Exception occured: " + ex.getMessage());
		}
		return EVAL_PAGE;
	}
	
	@Override
	protected StringBuffer paginatedTable() throws SQLException {
		StringBuffer stringBuffer = new StringBuffer();
		String[] columns = {};
		if(columnNames != null && columnNames.length > 0) {
			columns = columnNames;
			count = columns.length;
		}
		else {
			if(collection!=null) {
				Object object = collection.get(0);
				Field[] declaredFields = object.getClass().getDeclaredFields();
				count = declaredFields.length;
				columns = new String[count];
				for(int index = 0; index < count; index++) {
					columns[index] = declaredFields[index].getName();;
				}
			}
			else {
				throw new RuntimeException("The Collection object provided as an argument is Empty.");
			}
		}
		try {
			int z = 1;
			int totalNoOfRows = collection.size();
			int totalNoOfPages = totalNoOfRows / rowsPerPage ;
			if(totalNoOfRows%rowsPerPage > 0) {
				totalNoOfPages++;
			}

			stringBuffer.append("<thead>"); 
		    stringBuffer.append("<tr>"); 
    		if(select) {
    			stringBuffer.append("<td valign='top' align='center' style='" + this.defaultHeaderCssStyle() + "' class='" + this.headerStyle + "'>Select</td>");
    		}
		    for (int index = 1; index <= count; index++) {
				if(!columns[index - 1].equalsIgnoreCase("serialVersionUID")) {
		    		stringBuffer.append("<td id='" + index + "' style='" + this.defaultHeaderCssStyle() + "' class='" + this.headerStyle + "' nowrap='nowrap'>");
			    	stringBuffer.append(columns[index - 1]);
			    	stringBuffer.append("</td>");
				}
		   	}		
	    	stringBuffer.append("</tr>");  
	    	stringBuffer.append("</thead>"); 

	    	/*
	    	 * Logic to set the index values to fetch the objects from the Collection.
	    	 * This eliminates the full iteration of the Collection List and simply 
	    	 * fetches the objects required to be displayed depending on the currentPage
	    	 * and the number of rowsPerPage
	    	 */
	    	if(currentPage > totalNoOfPages) {
	    		currentPage = totalNoOfPages;
	    	}
			int fromIndex = (currentPage - 1) * rowsPerPage;
			int toIndex = currentPage * rowsPerPage;
			if(currentPage == totalNoOfPages) {
				toIndex = totalNoOfRows; 	
			}
	    	List<Object> subList = collection.subList(fromIndex, toIndex);
	    	
	    	stringBuffer.append("<tbody id='tableBody'>"); 
	    	for(Object c : subList) {
	    		stringBuffer.append("<tr valign='top'>");
		    	/* 
		    	 * If we are seeing the content of the table.
		    	 * We need to have a select box.
		    	 
		    	if(select) {
			    	stringBuffer.append("<td valign='top' style='" + this.defaultRowCssStyle() + "' class='" + this.rowStyle + "' align='center' width='20px'>");
			    	stringBuffer.append("<input type='checkbox' id='selectedRow' name='selectedRow' value=" + rst.getString(1) + ">");
			    	stringBuffer.append("</td>");
		    	}
		    	 */
	    		
		    	/*
		    	 * Code for printing the Column Values
		    	 */
		    	for (int i = 1; i <= count; i++) {
		    		if(columns[i - 1].equalsIgnoreCase("serialVersionUID")) {
		    			continue;
		    		}
		    		//Field field = c.getClass().getField(columns[i - 1]);
		    		Field field = c.getClass().getDeclaredField(columns[i - 1]);
		    		if(!field.isAccessible()) {
		    			field.setAccessible(true);
		    		}
		    		if(select && (i == 1)) {
		    			stringBuffer.append("<td valign='top' style='" + this.defaultRowCssStyle() + "' class='" + this.rowStyle + "' align='center' width='20px'>");
		    			stringBuffer.append("<input id='checkbox-" + z + "' type='checkbox' name='selectedRow' value='" + z + "'>");
		    			stringBuffer.append("</td>");
		    		}
			    	stringBuffer.append("<td id='column" + z + i + "' style='" + this.defaultRowCssStyle() + "' class='" + this.rowStyle + "' nowrap='nowrap' >");
		    		//Object data = field.get(field);
			    	Object data = field.get(c);
		    		if(data != null && data.toString().startsWith("<")){
		    			stringBuffer.append(this.parseXMLString(data.toString()));
		    		}
		    		else{
		    			stringBuffer.append(data.toString());
		    		}		    	
		        	stringBuffer.append("</td>");
			   	}		
		    	stringBuffer.append("</tr>");
		    	z++;
	    	}
	    	stringBuffer.append("</tbody>");


		    /*
		     * This will display a message when the table is without any rows.
		     */
		    if(collection.isEmpty()) {
		    	stringBuffer.append("<tr>");
		    	stringBuffer.append("<td colspan=" + (count + 1) + " style='" + this.defaultRowCssStyle() + "' class='" + this.rowStyle + "'><span style='color:red;'>The table is empty.</span></td>");
		    	stringBuffer.append("</tr>");
		    }
	    	
		    /*
		     * To display pagination
		     */
		    stringBuffer.append(showPagination(totalNoOfPages));

		    /*
		     * To get the number of rows count.
		     */
		    if(rowCountRequired) {
		    	stringBuffer.append("<tr>");
		    	stringBuffer.append("<td style='" + this.defaultFooterCssStyle() + "' class='" + this.footerStyle + "' colspan='" + (count + 1) + "'>");
		    	stringBuffer.append("Total Row Count: " + totalNoOfRows);
		    	stringBuffer.append("&nbsp;&nbsp;&nbsp;");
		    	stringBuffer.append("Page Row Count: " + (z - 1));
		    	stringBuffer.append("</td>");
		    	stringBuffer.append("</tr>");
		    }
		} catch (Exception e) {
			e.printStackTrace();
		}

		return stringBuffer;
	}
}
